<?php

class Diagrams {  
    const DATE_SIZE = 60;
    
    private static function get_rgb($color, &$r, &$g, &$b) {
            $r = substr($color, 0, 2);
            $g = substr($color, 2, 2);
            $b = substr($color, 4, 2);
            $r = hexdec($r);
            $g = hexdec($g);
            $b = hexdec($b);
    }

    public static function hue($i, $max, $max_color = 200) {
        if ($max % 6 != 0) {
            $max += 6 - ($max % 6);
        }
        $index = $i / $max * $max_color * 6;
        $per_part = $index % $max_color;
        $part = floor($i / $max * 6);
        switch ($part) {
            case 1:
                $r = $max_color;
                $g = $per_part;
                $b = 0;
            break;
            case 2:
                $r = $max_color - $per_part;
                $g = $max_color;
                $b = 0;
            break;
            case 3:
                $r = 0;
                $g = $max_color;
                $b = $per_part;
            break;
            case 4:
                $r = 0;
                $g = $max_color - $per_part;
                $b = $max_color;
            break;
            case 5:
                $r = $per_part;
                $g = 0;
                $b = $max_color;
            break;
            default:
                $r = $max_color;
                $g = 0;
                $b = $max_color - $per_part;
        }
        $a1 = $i * $max_color;
        $a2 = $max * $max_color / 6;
        return sprintf("%02X%02X%02X", $r, $g, $b);
    }
    
    public static function get_colors($time_groups, $max_color = 255) {
        $n = count($time_groups);
        $result = array();
        $i = 0;
        foreach ($time_groups as $subdivision=>$value) {
            $result[$subdivision] = self::hue($i, $n);
            $i++;
        }
        return $result;
    }
    
    private static function create_color($image, $color) {
        self::get_rgb($color, $r, $g, $b);
        return imagecolorallocate($image, $r, $g, $b);
    }
    
    /**
     * @param type $time_groups [line_names][x_axis]=>value
     */
    public static function draw($time_groups, $dates, $file, $colors, &$points, $cache_date = null, $width = 1000, $height = 300, $margin_left = 30, $margin_bottom = 40) {
        if ($cache_date == null || !file_exists($file) || strtotime($cache_date) > filemtime($file)) {
            $create_image = true;
        } else {
            $create_image = false;
        }
        if ($create_image) {
            $im = imagecreate($width, $height);
        }
        
        /* Max values and colors */
        $max_y = 0;
        $max_x = 0;
        $line_colors = array();
        foreach ($time_groups as $subdivision=>$line) {
            if ($create_image) {
                self::get_rgb($colors[$subdivision], $r, $g, $b);
                $line_colors[$subdivision] = imagecolorallocate($im, $r, $g, $b);
            }
            $max_x = max(count($line), $max_x);
            foreach ($line as $date=>$value) {
                $y = $value;
                $max_y = max($y, $max_y);
            }
        }
        $max_y++;
        
        /* Background */
        if ($create_image) {
            $background = self::create_color($im, "FCFCFF");
            $grid_color = self::create_color($im, "F0F0F3");
            $predicted_color = self::create_color($im, "D0D0E3");
            imagefill($im, 0, 0, $background);
        }
        
       
        /* Axis */
        if ($create_image) {
            $foreground = self::create_color($im, "000000");
            self::draw_legend_x($im, $dates, $margin_left, $margin_bottom, $width, $height, $foreground, $grid_color, $predicted_color);
            self::draw_legend_y($im, $margin_left, $margin_bottom, $max_y, $foreground, $grid_color, $width, $height);
        }
        
        /* Lines */
        $step_x = ($width - $margin_left - self::DATE_SIZE) / $max_x;
        $step_y = ($height - $margin_bottom) / $max_y;
        foreach ($time_groups as $subdivision=>$line) {
            $i_x = 0;
            $last_x = null;
            $last_y = null;
            foreach ($line as $date=>$value) {
                $y = $height - ($margin_bottom + $value * $step_y);
                $x = $margin_left + $i_x * $step_x;
                if ($create_image) {
                    $color = $line_colors[$subdivision];
                    if ($last_x !== null && $last_y != null) {
                        imageline($im, $last_x, $last_y, $x, $y, $color);
                    }
                    imageellipse($im, $x, $y, 4, 4, $color);
                }
                $short_code = strtolower("legend_line_$subdivision");
                $date_text = $dates[$date] ? $date . ' numatoma' : $date;
                $points[] = array('x'=>$x, 'y'=>$y, 'x_axis'=>$date_text, 'y_axis'=>$value, 'legend_id'=>$short_code);
                $i_x++;
                $last_x = $x;
                $last_y = $y;
            }
        }
        
        /* Exporting */
        if ($create_image) {
            if (is_writable(dirname($file))) {
                imagegif($im, $file);
            } else if (is_writable(sys_get_temp_dir())) {                
                $file = sys_get_temp_dir() . '/' . basename($file);
                imagegif($im, $file);
            } else {
                add_error("Sistemai nėra suteiktos rašymo į katalogą <i>$dir_name</i> teisės. Todėl negalima optimizuoti paveikslėlių.");
            }
            imagedestroy($im);
        }
        return $file;
    }
    
    private static function draw_legend_y($image, $margin_left, $margin_bottom, $max_y, $color, $grid_color, $width, $height) {
        $font = 0;
        $real_font_height = imagefontheight($font);
        $text_height = $real_font_height * 2;
        $divider = ($height - $margin_bottom) / $text_height;
        $step_y = $max_y / $divider;
        
        /* Grid */
        for ($i = 0; $i <= $divider; $i++) {
            $y = floor($height - $i * $text_height - $margin_bottom);
            imageline($image, $margin_left, $y, $width - self::DATE_SIZE, $y, $grid_color);
        }
        
        /* Numbers */
        for ($i = 0; $i <= $divider; $i++) {
            $y = floor($height - $i * $text_height - $margin_bottom);
            $value = floor($i * $step_y);
            imagestring($image, $font, 0, $y, $value, $color);
        }
    }

    private static function draw_legend_x($image, $series, $margin_left, $margin_bottom, $width, $height, $color, $grid_color, $predicted_color, $font = 0) {
        $step_width = ($width - $margin_left - self::DATE_SIZE) / count($series);
        $x = $margin_left;
        $y_base = $height - $margin_bottom;
        $floors = round(self::DATE_SIZE / $step_width);
        $floor = 0;
        $floor_size = imagefontheight($font) * 1.2;
        $i = 0;
        $n = count($series);
        foreach ($series as $date=>$predicted) {
            $y = $y_base + ($floor * $floor_size);
            if ($predicted) {
                imagefilledrectangle($image, $x, 0, $x + $step_width, $y_base - 1, $predicted_color);
            }
            imageline($image, $x, 0, $x, $y_base, $grid_color);
            if ($i < $n && $x + self::DATE_SIZE < $width) {
                imagestring($image, $font, $x, $y, $date, $color);
            }
            $floor++;
            if ($floor >= $floors) {
                $floor = 0;
            }
            $x += $step_width;
            $i++;
        }
    }
    
    public static function clear_cache() {
        $chace_dir = dirname(dirname(dirname(__FILE__))) . '/Cache';
        if (is_dir($chace_dir) && is_writable($chace_dir)) {
            foreach (glob("$chace_dir/*.gif") as $image) {
                unlink($image);
            }
        }
    }
}